/*
#Copyright (c) 2013, Philippe Bordron <philippe.bordron@gmail.com>
#
# This file is part of SIPPER.
#
# DCC is free software: you can redistribute it and/or modify
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU LESSER GENERAL PUBLIC LICENSE for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# along with SIPPER.  If not, see <http://www.gnu.org/licenses/>
*/
package combi.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class GenerateAllSubsets<T>
{
	private List<T> data; // original data
	private double numberOfSubsets; // number of subsets
	private int subsetInProgress; // subset in progress.
	private List<T> subsetInProgressData; // data of the subset in progress

	public GenerateAllSubsets(List<T> data)
	{
		this.data = data;
		this.subsetInProgressData = new ArrayList<T>(data.size());
		subsetInProgress = 0;
		numberOfSubsets = Math.pow(2, data.size());
	}

	public List<T> getArrangement(int subsetId)
	{
		double temp = subsetId;
		List<T> result = null;
		if (subsetId < numberOfSubsets)
		{
			result = new LinkedList<T>();
			for (int i = data.size()-1; i >= 0 ; i--)
			{
				double temp2 = Math.pow(2, i);
				if(temp >= temp2)
				{
					temp = temp - temp2; 
					result.add(data.get(i));
				}
			}
			Collections.reverse(result);
		}
		return result;
	}

	public List<T> getFirst()
	{
		subsetInProgressData.add(data.get(0));
		subsetInProgress = 1;
		return new LinkedList<T>(subsetInProgressData);
	}

	public boolean hasNext()
	{
		return subsetInProgress < (numberOfSubsets-1);
	}

	public List<T> next()
	{
		subsetInProgress++;			
		return getArrangement(subsetInProgress);
	}


	public static void main(String[] args) {
		Integer[] tab = {1, 2, 3 ,4, 5};
		List<Integer> l = Arrays.asList(tab);
		GenerateAllSubsets<Integer> subsets = new GenerateAllSubsets<Integer>(l);
		while (subsets.hasNext())
		{
			System.out.println(subsets.next());
		}
	}
}
